﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using CeskyRozhlasRT.DataModel;
using System.Net;

namespace CeskyRozhlasRT.Parsing
{
    public static class GroupConfigParser
    {
        private class ParserState
        {
            public WebContentDescription Content;
            public HttpWebRequest Request;
            public IEnumerable<XElement> GroupDefs;
        }


        public static SynchronizationContext SyncContext { get; set; }

        public static void ParseGroupConfig(XmlReader iXmlReader, WebContentDescription oParsedContent)
        {
            var aAppConfigXml = XDocument.Load(iXmlReader);
            var parserState = new ParserState
            {
                GroupDefs = aAppConfigXml.Root.Elements("groupdef"), 
                Content = oParsedContent
            };
            var aRadioConfigUri = aAppConfigXml.Root.Element("radioconfiguri").Attribute("href").Value;
            using (XmlReader aReader = StationsRetriever.AssetManager.GetXmlReader(aRadioConfigUri))
            {
                RetrieveStationsList(aReader, parserState);
            }
        }


        public static void ParseGroupConfigAsync(XmlReader iXmlReader, WebContentDescription oParsedContent)
        {
            var aAppConfigXml = XDocument.Load(iXmlReader);
            var aRadioConfigUri = aAppConfigXml.Root.Element("radioconfiguri").Attribute("href").Value;
            var request = (HttpWebRequest)WebRequest.Create(aRadioConfigUri);
            request.BeginGetResponse(WebResponseCallback, new ParserState
            {
                Content = oParsedContent, 
                Request = request,
                GroupDefs = aAppConfigXml.Root.Elements("groupdef")
            });
        }

        private static void WebResponseCallback(IAsyncResult iAsyncResult)
        {
            var asyncData = iAsyncResult.AsyncState as ParserState;
            if (asyncData != null)
            {
                var response = asyncData.Request.EndGetResponse(iAsyncResult) as HttpWebResponse;
                if (response != null)
                {
                    RetrieveStationsList(XmlReader.Create(response.GetResponseStream()), asyncData);
                }
            }
        }



        private static void RetrieveStationsList(XmlReader aReader, ParserState oState)
        {
            var aRetriever = new StationListWebRetriever();
            aRetriever.ParseXmlStationsList(aReader);

            foreach (var aGroupDef in oState.GroupDefs)
            {
                var aGeneralStations = new StationsGroup(
                    aGroupDef.Attribute("uid").Value,
                    aGroupDef.Attribute("title").Value,
                    aGroupDef.Attribute("subtitle").Value,
                    aGroupDef.Attribute("imagepath").Value,
                    aGroupDef.Attribute("description").Value);
                var aRegexFilter = aGroupDef.Attribute("typeRegexFilter").Value;
                foreach (
                    var aCurrentStation in
                        aRetriever.StationsList.Where(
                            aCurrentStation =>
                                (aCurrentStation != null && Regex.IsMatch(aCurrentStation.Type, aRegexFilter))))
                {
                    aGeneralStations.Items.Add(aCurrentStation);
                }
                SyncContext.Post((usersuppliedstate) => oState.Content.Groups.Add(usersuppliedstate as StationsGroup), aGeneralStations);
            }
        }
    }
}
